<!-- 座席报表 -->
<template>
  <div class="report_main">
      <tabs :tabPane="tabPaneList" v-model="activeName" @tab-click='toSerach' />
      <continer class="webchatContainer">
        <template slot="search">
          <quickSearch v-if="flag"  :advForm="quickSearchForm" ></quickSearch>
          <quickSearch v-else :advForm="quickSearchForm2" ></quickSearch>
        </template>
        <template slot="oprate">
          <el-popover
            ref="popover"
            v-model="quickSearchForm.form.openPeriod"

            placement="bottom"
            width="387"
            trigger="click"
            popper-class="custom-search-pop"
            >
            <div class="query-main">
              <div class="query-title">
                <span>更多筛选</span>
              </div>
              <div class="query-content">
                <p>定时段</p>
                  <el-time-select
                    placeholder="起始时间"
                    style="width: 45%"
                    v-model="quickSearchForm.form.periodRange[0]"
                    :picker-options="{
                      start: '00:00',
                      step: '00:30',
                      end: '23:59'
                    }">
                  </el-time-select>
                  <div class="spacer"></div>
                  <el-time-select
                    placeholder="结束时间"
                    style="width: 45%; float: right"
                    v-model="quickSearchForm.form.periodRange[1]"
                    :picker-options="{
                      start: '00:00',
                      step: '00:30',
                      end: '24:00',
                      minTime: quickSearchForm.form.periodRange[0]
                    }">
                  </el-time-select>
                <div class="operation" >
                  <el-button  type="primary" @click="timingSegmentSearch(true)">检索</el-button>
                </div>
              </div>
            </div>
          </el-popover>
        <el-button slot="reference" size="mini" style="padding: 6px 12.3px" v-show="flag"  v-popover:popover>
          <i class="V7_iconfont V7_iconV7tubiao_shaixuan"  style="font-size: 12px"></i>
          更多
        </el-button>
          <el-button type="primary" size="mini" @click="toSerach(false)">查询</el-button>
          <el-button  size="mini" @click="toSerach(false)">刷新</el-button>
        </template>
        <template slot="content">
          <p class="overviewOfConversation">会话整体概览</p>
          <div class="tags">
            <div v-for="i in tagList" class="tag" :key="i.name">
              <div>
                <p class="describe">{{i.name}}<br></p>
                <p class="number">{{i.value}}</p>
              </div>
            </div>
          </div>
          <p class="overviewOfConversation">趋势</p>
          <div id="timeTrend" v-show="flag" />
          <div id="displayName" class="charts" v-show="!flag"></div>
          <p class="overviewOfConversation lh30">
          <span class="xiangqing" style="margin-right: 6px">详情</span>
          <span class="V7_iconfont V7_iconV7tubiao_bangzhu-42  myIcon" style='color: #B3B9C7' v-popover:explainPopover></span>
          <!-- <el-button @click="jisuan(tableData, formulaList)">测试</el-button> -->
          <span class="floatRight" style="cursor: pointer;">
            <span class="slider">
              <span :class="timeState === 'second' ? 'selected':''" @click="timeStateChange('second')">秒</span>
              <span :class="timeState !== 'second' ? 'selected':''" @click="timeStateChange('HMS')">时分秒</span>
            </span>
            <!-- 表头设置 -->
            <el-dropdown trigger="click" @visible-change="headerChange">
              <span class="el-dropdown-link">
                <i title="自定义表头" class="V7_iconfont V7_iconV7tubiao_zidingyi fz14" :class="isClick? 'icon-active': ''"></i>
              </span>
              <el-dropdown-menu slot="dropdown">
                <searchCheckBox
                  :data="realHeader"
                  @check-change="handleCheckChange"
                ></searchCheckBox>
              </el-dropdown-menu>
            </el-dropdown>
            <!-- 自定义公式 -->
            <i title="自定义公式" @click="showDrawer" style="margin-left: 20px" class="V7_iconfont V7_iconV7tubiao_gongshi fz14"></i>

            <!-- 导出 -->
            <el-popover

              placement="top"
              width="100"
              trigger="click"
              popper-class="custom-search-pop"
              >
              <p style="margin-top: 6px" class='exportReport' @click="exportReport('part')">导出当前表格</p>
              <p style="margin-bottom: 6px" class='exportReport' @click="exportReport('all')">导出详细信息</p>
              <i  slot="reference" title="导出" style="margin-left: 20px" class="V7_iconfont V7_iconV7tubiao_daochu fz14"></i>
            </el-popover>
          </span>
        </p>
        <uTable style="min-height:150px" v-loading='tableLoading' :key="tableKey"  :tableHeaders='actualHeader' :tableData="tableData"></uTable>
        <div style="width: 100%;height: 20px"></div>
        </template>
      </continer>
       <CustomFormula ref='Custom' :nowHeader="nowHeader" :delUrl="delUrl" :formulaType="formulaType" :show.sync='toshow' :formulaList='formulaList' @getCustomFormula='getCustomFormula' @delCustomFormula='delCustomFormula' @saveCustomFormula='saveCustomFormula' @cancelFun='cancelFun'> </CustomFormula>
        <el-popover
          ref="explainPopover"
          placement="top"
          width="500"
          trigger="hover"
          popper-class="custom-search-pop"
          >
         <div class='explainMain'>
           <p v-for="item in nowHeader.filter(i => i.notes)" :key="item.label"><span style="color:#303753">{{item.label}}: </span><span style="color:#686E84">{{item.notes}}</span></p>
         </div>
        </el-popover>
  </div>
</template>

<script lang='ts'>
import { Component, Vue } from 'vue-property-decorator'
import tabs from '@/components/configCommon/configTabs.vue'
import continer from '@/common/views/configCommon/ui-modules/handle-wrapper.vue'
import quickSearch from '@/common/views/advancedSearch/QuickSearch.vue'
import customSearch from '@/views/dataCenter/callData/customSearch.vue'
import searchCheckBox from '@/components/configCommon/operate-modules/SearchCheckbox/index.vue'
import { uTable, CheckBox, CheckBoxItem, OtherSelect, Loading, CustomFormula } from './components/index'
import { commonAction, deepClone, getFormatDateTime, isHasFuncOrMenus } from '@/utils/common'
import { ExportExcel } from '../../../../public/static/js/worker' // 导出
import * as formula from './base/formulaUtil' // 自定义公式相关
import { drawCharts, timeTrend2, displayName } from './base/echart'
import { selfTimeSetting2 } from './base/timeSetting'
import { timeTrendHeader } from './base/tableHeader/callHeader'
import { tableHeaders } from './base/tableHeader/header'
import { WebchatModule } from '@/store/modules/webchat'

const method = 'post'

@Component({
  name: 'outCallReport',
  components: { CustomFormula, tabs, continer, quickSearch, searchCheckBox, uTable, customSearch }
})
export default class OutCallReport extends Vue {
  private $store
  private activeName = 'timeTrend'
  private tabPaneList = [
    {
      label: '时间趋势',
      name: 'timeTrend',
      _id: 'im_agent_report'
    },
    {
      label: '外显号',
      name: 'displayNumber',
      _id: 'im_agent_quality_report'
    }
  ]

  private permissionControl () {
    const arr = ['im_agent_report', 'im_agent_quality_report']
    const newArr: any[] = []
    arr.forEach((item: string) => {
      if (isHasFuncOrMenus(item, this.$store.state.common.session.user, true)) {
        newArr.push(item)
      }
    })
    this.tabPaneList = this.tabPaneList.filter(item => newArr.indexOf(item._id) > -1)
    this.activeName = this.tabPaneList[0] ? this.tabPaneList[0].name : 'agentWork'
  }

  get flag () {
    return this.activeName === 'timeTrend'
  }

  get nowHeader () {
    return timeTrendHeader
  }

  private quickSearchForm: any = {
    // 快捷检索数据（时间条件，类型）
    form: {
      startTime: [
        // 创建时间 默认显示最近七天
        getFormatDateTime(new Date(new Date().getTime() - 3600 * 1000 * 24 * 1), '').split(' ')[0] + ' 00:00:00',
        getFormatDateTime(new Date(new Date().getTime() - 3600 * 1000 * 24 * 1), '').split(' ')[0] + ' 23:59:59'
      ],
      displayNumbers: [], // 座席列表
      dimension: 'half_hour', // 维度
      // openPeriod: false, // 是否开启定时间段查询
      periodRange: ['00:00', '24:00'], // 开启定时间段的数据
      time1: getFormatDateTime(new Date(new Date().getTime() - 3600 * 1000 * 24 * 1), '').split(' ')[0],
      time2: '00:00',
      time3: getFormatDateTime(new Date(new Date().getTime() - 3600 * 1000 * 24 * 1), '').split(' ')[0],
      time4: '24:00'
    },

    advSearchOptions: [],
    selfPickerOptions: selfTimeSetting2
  }

  private quickSearchForm2: any = {
    form: {
      startTime: [
        // 创建时间 默认显示最近七天
        getFormatDateTime(new Date(new Date().getTime() - 3600 * 1000 * 24 * 1), '').split(' ')[0] + ' 00:00:00',
        getFormatDateTime(new Date(new Date().getTime() - 3600 * 1000 * 24 * 1), '').split(' ')[0] + ' 23:59:59'
      ],
      displayNumbers: [], // 座席列表
      time1: getFormatDateTime(new Date(new Date().getTime() - 3600 * 1000 * 24 * 1), '').split(' ')[0],
      time2: '00:00',
      time3: getFormatDateTime(new Date(new Date().getTime() - 3600 * 1000 * 24 * 1), '').split(' ')[0],
      time4: '24:00'
    },
    advSearchOptions: [],
    selfPickerOptions: selfTimeSetting2
  }

  private timingSegmentSearch () {
    if (!this.quickSearchForm.form.periodRange[0] || !this.quickSearchForm.form.periodRange[1]) {
      (this as any).$message.warning('请选择开始时间结束时间')
      return
    }
    this.toSerach()
  }

  private toSerach () {
    setTimeout(() => {
      this.dataQuery()
    }, 200);
  }

  private tagList = [
    { name: '外呼总数', prop: 'outgoingCount', value: '0' },
    { name: '外呼失败数', prop: 'failed', value: '0' },
    { name: '外呼振铃未接听数', prop: 'ringNotAnswered', value: '0' },
    { name: '外呼接通数', prop: 'answered', value: '0' }
  ]

  private webchatStatusList: any = []
  private webchatStatusMap = new Map()
  private headerChange (val) { // 表头修改
    if (!val) {
      const url = '/base/report/headers'
      this.actualHeader.forEach(element => {
        if (element.prop.includes('-')) {
          element.customized = true
        } else {
          element.customized = false
        }
        if (element.prop === 'answered') {
          element.label = timeTrendHeader.find(i => i.prop === 'answered')?.label
        }
      });
      const data = { type: this.formulaType, headers: this.actualHeader }
      commonAction({ url, method: 'post', data }).then(res => {
        this.headerQuery()
      })
    }
  }

  private async mounted () {
    // this.permissionControl()
    this.quickSearchForm.advSearchOptions = [
      // 快捷检索的数据
      { label: '维度', inputType: 'select', selectData: this.stateOptions, name: 'dimension' },
      // {
      //   label: '时间',
      //   inputType: 'dateTimeRange',
      //   clearable: false,
      //   name: 'startTime'
      // },
      { label: '开始日期', inputType: 'date', name: 'time1' },
      { label: '开始时间', inputType: 'timeselect', name: 'time2' },
      { label: '结束日期', inputType: 'date', name: 'time3' },
      { label: '结束时间', inputType: 'timeselect', name: 'time4' }
      // { label: '接入号', inputType: 'select',  selectData: this.$store.state.common.publicCache.channelList, defaultProp: {label: 'agentName', value: '_id'} },
    ]
    this.quickSearchForm2.advSearchOptions = [
      // { label: '时间', inputType: 'dateTimeRange', clearable: false, name: 'startTime' }
      { label: '开始日期', inputType: 'date', name: 'time1' },
      { label: '开始时间', inputType: 'timeselect', name: 'time2' },
      { label: '结束日期', inputType: 'date', name: 'time3' },
      { label: '结束时间', inputType: 'timeselect', name: 'time4' }
    ]
    await this.dataQuery()
    this.getDisplayNumber()
  }

  get toDisplayNumber () {
    const list = deepClone(this.displayNumber)
    for (let i = 0; i < list.length; i++) {
      const e = list[i]
      if (e.status === 'disable') {
        e.realName = e.number + ' ' + e.name + ' (停用)'
      } else {
        e.realName = e.number
      }
    }
    return list
  }

  private displayNumber = []
  private getDisplayNumber () {
    const url = '/call/action/general/displayNumbers'
    const data = {}
    commonAction({ url, method: 'get', data }).then(res => {
      this.displayNumber = res.data
      this.quickSearchForm.advSearchOptions.push(
        { label: '外显号', inputType: 'select', selectData: this.toDisplayNumber, name: 'displayNumbers', filterable: true, multiple: true, clearable: true, defaultProp: { label: 'realName', value: 'number' } }
      )
      this.quickSearchForm2.advSearchOptions.push(
        { label: '外显号', inputType: 'select', selectData: this.toDisplayNumber, name: 'displayNumbers', filterable: true, multiple: true, clearable: true, defaultProp: { label: 'realName', value: 'number' } }
      )
    })
  }

  private stateOptions: object[] = [
    { name: '半小时', _id: 'half_hour' },
    { name: '一小时', _id: 'hour' },
    { name: '一天', _id: 'day' },
    { name: '月', _id: 'month' },
    { name: '年', _id: 'year' }
  ]

  private valData: any = []
  private async dataQuery () {
    this.tableLoading = true
    const url = this.flag ? '/report/outgoing/trend' : '/report/outgoing/displayNumber'
    const data = this.flag ? this.quickSearchForm.form : this.quickSearchForm2.form
    data.startTime = [`${data.time1} ${data.time2}`, `${data.time3} ${data.time4}`]
    await commonAction({ url, method, data }).then(res => {
      if (res.success) {
        this.total = {}
        this.tableData = []
        if (res.data.length) {
          this.valData = res.data
        } else {
          this.valData = []
          this.getTotal(res.data)
        }
        this.headerQuery()
      }
      this.tableKey++
      this.chartInit()
    })
  }

  private async headerQuery () { // 表头查询
    const url = '/base/report/headers'
    const data = { type: this.flag ? 'outgoing-trend' : 'outgoing-display-number' }
    // console.log(otherHeader)
    await commonAction({ url, method: 'GET', data }).then(res => {
      if (res.success) {
        this.headerInit(res.data.headers)
        this.getCustomFormula(false, true)
      }
    })
  }

  private list = [
    { name: '接待会话总数', code: 'initCount' },
    { name: '分配会话数', code: 'assignCount' },
    { name: '有效会话数', code: 'invalidCount' },
    { name: '主动会话数', code: 'inviteCount' },
    { name: '处理留言数', code: 'delLeavingCount' }
  ]

  private chartInit () {
    const resizeWidth = document.querySelector('.header-contain')?.scrollWidth || 300
    const data = this.flag ? deepClone(timeTrend2) : deepClone(displayName)
    for (let m = 0; m < this.valData.length; m++) {
      const e: any = this.valData[m]
      if (e.flag === '总计') {
        continue
      }
      if (this.flag) {
        data.xAxis.data.push(e.showTime)
      } else {
        data.xAxis.data.push(e.displayNumber)
      }

      for (let i = 0; i < data.series.length; i++) {
        const element = data.series[i]
        element.data.push(e[element.code])
      }
    }
    const id = this.flag ? '#timeTrend' : '#displayName'
    this.$nextTick(() => {
      drawCharts(id, data, { width: resizeWidth, height: 300 })
    })
  }

  private headerInit (arr: any = [], flag = true) {
    const item = arr?.find(i => i.prop === 'showTime')
    if (item) {
      item.disenable = true
      item.fixed = 'left'
    }
    if (flag) {
      this.$set(this, 'realHeader', arr)
    }
    this.$set(this, 'actualHeader', arr)
  }

  private otherHeaders = []
  private actualHeader: any = []
  private tableData: any = []
  private tableLoading = false

  private toshow = false
  private formulaList: any = []
  private showDrawer () {
    this.toshow = true
    this.getCustomFormula()
  }

  private customFormulaHeader: any = []
  private getCustomFormula (ast?: any, flag?: any) {
    const list = deepClone(this.actualHeader)
    const url = '/base/report/formulas'
    const data = { type: this.flag ? 'outgoing-trend' : 'outgoing-display-number' }
    commonAction({ url, method: 'GET', data }).then(res => {
      if (res.success) {
        this.$set(this, 'formulaList', res.data)
        this.getCustomFormulaHeader(this.formulaList)
        for (let i = 0; i < list.length; i++) {
          const element = list[i]
          if (element.customized) {
            if (!this.formulaList.find(item => item._id === element.prop)) {
              list.splice(i, 1)
              i--
            }
          }
        }
        this.customFormulaHeader.forEach(element => {
          try {
            if (!(list.find(item => item.prop === element.prop))) {
              list.push(element)
            } else {
              const val = list.find(item => item.prop === element.prop)
              val.label = element.label
            }
          } catch (error) {
            console.error(list)
          }
        })
        this.headerInit(list)
        if (flag) {
          setTimeout(() => {
            let realdata
            const f = this.valData.find(i => i.flag === '总计')
            if (f) {
              realdata = this.valData
            } else {
              realdata = this.valData.concat(this.getTotal(this.valData))
            }
            formula.jisuan(realdata, this.formulaList).then((val: any) => {
              if (!this.valData.length) {
                val = []
              }
              this.timeStateChange('HMS', val)

              this.tableLoading = false
            })
          }, 200)
        }
      }
    })
  }

  private getCustomFormulaHeader (arr: any[]) {
    const list: any = []
    arr.forEach(item => {
      let flag = false
      for (const key in item.variables) {
        if (item.variables[key].includes('Duration')) {
          flag = true
        }
      }
      list.push({
        label: item.formulaName,
        prop: item._id,
        width: 120,
        show: true,
        customized: true,
        formulaStr: item.formulaStr,
        variables: item.variables,
        digits: item.digits,
        HMS: flag
      })
    })
    this.customFormulaHeader = list
  }

  private getSatisfactionHeader (arr) {
    const list: any = []
    arr.forEach(element => {
      list.push({
        label: element.name + '比例',
        prop: element.key,
        show: true,
        type: 'percentage',
        noCalculation: true
      })
    })
    return list
  }

  get formulaType () {
    return this.flag ? 'outgoing-trend' : 'outgoing-display-number'
  }

  private delCustomFormula (val) {
    //
  }

  private delUrl = '/base/report/formulas/del'
  private saveCustomFormula (data, flag) {
    const url = '/base/report/formulas'
    commonAction({ url, method, data }).then(res => {
      if (res.success) {
        this.toshow = false;
        (this as any).$message.success(flag ? '添加成功' : '修改成功');
        (this.$refs.Custom as any).reset()
        this.getCustomFormula(false, true)
      }
    })
  }

  private cancelFun () {
    (this.$refs.Custom as any).reset()
    this.getCustomFormula(false, true)
  }

  private format (time) {
    time = '' + time
    const flag = time.charAt(0) === '-'
    if (flag) {
      time = time.substr(1)
    }
    if (time.charAt(time.length - 1) === 's') {
      time = time.substr(0, time.length - 1)
      return Number(time)
    }
    const hour = time.split(':')[0];
    const min = time.split(':')[1];
    const sec = time.split(':')[2];
    const number = Number(hour * 3600) + Number(min * 60) + Number(sec)
    if (flag) {
      return -number
    }
    return number
  }

  private total = {}
  private getTotal (arr) { // 求合计
    arr = arr || []
    const total: any = {}
    const obj = arr[0] || {}
    Object.keys(obj).forEach(item => {
      total[item] = 0
    })
    for (let i = 0; i < arr.length; i++) {
      const element = arr[i]
      for (const key in total) {
        if (isNaN(element[key])) {
          if ((element[key] + '').includes(':')) {
            total[key] += Number(this.format(element[key]))
          } else {
            total[key] = 0
          }
        } else {
          total[key] += Number(element[key])
        }
      }
    }
    if (this.flag) {
      total.showTime = '总计'
    } else {
      total.displayNumber = '总计'
    }
    total.answerRate = (total.answered / total.outgoingCount).toFixed(4)
    total.avgRingDuration = (total.ringDuration / total.outgoingCount).toFixed(0)
    total.avgCallDuration = (total.callDuration / total.answered).toFixed(0)
    total.flag = '总计'
    this.total = total
    this.totalToTags()
    return total
  }

  private totalToTags () {
    for (let i = 0; i < this.tagList.length; i++) {
      const element = this.tagList[i]
      element.value = this.total[element.prop] || '0'
    }
  }

  private handleCheckChange (arr, flag) {
    if (arr.length) {
      this.headerInit(arr, false)
    }
    // console.log(arr)
  }

  private getNumber (val) {
    if (isNaN(Number(val))) {
      return '--'
    } else {
      return Number(val).toFixed(2)
    }
  }

  private realHeader = []
  // get realHeader () {
  //   return deepClone(this.actualHeader)
  // }
  private exportReport (val) {
    const header = deepClone(this.actualHeader)
    const tableData = deepClone(this.tableData)
    const year = new Date().getFullYear() + ''
    const month = new Date().getMonth() + 1 + ''
    const day = new Date().getDay() + ''
    const time = `${year}${month}${day}`
    const name = `${time}-${this.$store.state.common.session.user.agentName || ''}-会话报表`
    if (val === 'all') {
      const de = new ExportExcel(header, tableData)
      de.toExport(name)
    } else {
      const de = new ExportExcel(header.filter(item => item.show), tableData)
      de.toExport(name)
    }
  }

  // timeConversion
  private tableKey = 0
  private isClick = false
  private timeState = 'second' // 时分秒: HMS

  private timeStateChange (val, data?: any) {
    data = data || this.tableData
    const nowHeader = this.nowHeader
    const list1 = this.customFormulaHeader.concat(nowHeader).filter(item => item.HMS)
      .map(i => i.prop)
    const list2 = this.customFormulaHeader.concat(nowHeader).filter(item => item.type === 'percentage').map(i => i.prop)
    const timeTransformation = require('./base/timeConversion')
    this.timeState = val
    const db = val === 'second' ? timeTransformation.formatHSM : timeTransformation.formatSeconds
    data.forEach(element => {
      list1.forEach(r => {
        element[r] = db(element[r])
      })
      list2.forEach(s => {
        element[s] = getval(element[s])
      })
    });
    this.$set(this, 'tableData', deepClone(data))
    this.tableKey++
    function getval (v) {
      if (v === '--') {
        return '--'
      }
      if ((v + '').includes('%')) {
        return v
      }
      if (isNaN(Number(v))) {
        return '0%'
      } else {
        if ((v + '').includes('.')) {
          return Number(v * 100).toFixed(2) + '%'
        } else {
          if (v === 1) {
            return '100%'
          }
          return Number(v * 100).toFixed(2) + '%'
        }
      }
    }
  }
}

</script>
<style lang='stylus' scoped>
@import './css/index.styl'
.tags
  height 90px
  .tag
    width 25%
    height 100%
    .number
      font-size: 24px;
      font-family: PingFang SC;
      font-weight: bold;
      color: #303753;
</style>
<style lang='stylus'>
.custom-search-pop
  padding 0
  min-width unset
.report_main .handle-wrapper
  padding-bottom 20px

.explainMain
  padding 14px
  height 210px
  overflow auto
.spacer
  display inline-block
  width: 10px;
  background: #ccc;
  height: 3px;
  margin-left: 13px;
  vertical-align: middle;
</style>
